/**
 *
 *
 **/
package mwt.xml.xdbforms.dblayer.impl.drivermanager;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import mwt.xml.xdbforms.dblayer.ConnectionFactory;
import mwt.xml.xdbforms.dblayer.metadata.CatalogMetaData;
import mwt.xml.xdbforms.dblayer.metadata.TableMetaData;
import mwt.xml.xdbforms.dblayer.metadata.impl.JDBCTableMetaDataDM;
import mwt.xml.xdbforms.dblayer.query.Query;
import mwt.xml.xdbforms.dblayer.query.impl.drivermanager.JDBCQuery;

/**
 * Questa classe implementa una factory di connessioni
 * utilizzando il DriverManager
 * @author Gianfranco Murador, Matteo Ferri, Cristian Castiglia
 */
public class ConnectionFactoryImpl extends ConnectionFactory {

    private String username;
    private String password;
    private String url;
    private static Properties properties;
    /**
     * Carico il driver ed il file di proprietà in questo punto
     **/


    static {

        try {
            Properties prop = new Properties();
            InputStream inStream =
                    ClassLoader.getSystemResourceAsStream("mwt/xml/xdbforms/configuration/xdbforms.properties");

            prop.load(inStream);
            // Carica il driver
            Class.forName(prop.getProperty("database.driver"));

            // Uso questa variabile per prendere gli altri parametri
            // nel costruttore
            ConnectionFactoryImpl.properties = prop;



        } catch (ClassNotFoundException ex) {
            System.err.println("Error: jdbc driver not detected");
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            System.err.println("Error: file properties not detected");
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    public ConnectionFactoryImpl() {
        super();
        this.password = ConnectionFactoryImpl.properties.getProperty("database.password", "");
        this.username = ConnectionFactoryImpl.properties.getProperty("database.username");
        this.url = ConnectionFactoryImpl.properties.getProperty("database.url");

    }

    @Override
    public Query getQuery() {

        return new JDBCQuery(username, password, url, getDatabase());

    }

    @Override
    public TableMetaData getTableMetaData(String table) {
        return new JDBCTableMetaDataDM(table, username, password, url + getDatabase());
    }

    /***
     *
     * @return Specifica implementazione dell'interfaccia
     * DatabaseMetaData estesa. Si potrebbe inoltrare
     * un controllo più intelligente per istanziare la giusta
     * implementazione per ogni vendor
     */
    @Override
    public CatalogMetaData getDatabaseMetaData() {

        String className =
                ConnectionFactoryImpl.properties.getProperty("jdbc.drivermanager.catalogmdimpl");
        Class classDef;
        try {
            classDef = Class.forName(className);
            Class[] args = new Class[]{String.class, String.class, String.class};
            Object[] vargs = new Object[]{username, password, url + getDatabase()};
            Constructor c = classDef.getConstructor(args);
            CatalogMetaData cmd = (CatalogMetaData) c.newInstance(vargs);

            return cmd;

        } catch (InstantiationException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(ConnectionFactoryImpl.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;


//        return new MySQLCatalogMetaDataDM(username, password, url + getDatabase());


    }
}
